package st.learnopengl.apps.basic

import gln.BufferTarget
import gln.Usage
import gln.VertexAttrType
import gln.glf.VertexAttribute
import gln.identifiers.GlBuffer
import gln.identifiers.GlProgram
import gln.vertexArray.glEnableVertexAttribArray
import gln.vertexArray.glGenVertexArray
import gln.vertexArray.glVertexAttribPointer
import st.learnopengl.common.App
import st.learnopengl.common.GLUT
import org.lwjgl.opengl.GL11
import org.lwjgl.opengl.GL15.*
import org.lwjgl.opengl.GL30.glBindVertexArray
import java.nio.ByteBuffer
import java.nio.ByteOrder

class HelloTriangle(width: Int, height: Int, title: String) : App(width, height, title) {

    private var program: GlProgram? = null
    private var vao : Int = -1
    private var vbo: GlBuffer? = null
    private lateinit var vboAttr: VertexAttribute

    override fun onInit() {
        program = GLUT.createProgram("shaders/basics/vertexShader.glsl"
            , "shaders/basics/fragmentShader.glsl")
        vao = glGenVertexArray()
        glBindVertexArray(vao)
        vbo = GlBuffer(glGenBuffers())
        vbo?.bound(BufferTarget.ARRAY) {
            val vertexs = listOf<Float>(
                -0.5f, -0.5f, 0.0f, // left
                0.5f, -0.5f, 0.0f, // right
                0.0f,  0.5f, 0.0f  // top
            )
            val bb = ByteBuffer.allocateDirect(vertexs.size * 4)
            bb.order(ByteOrder.nativeOrder())
            val fb = bb.asFloatBuffer()
            vertexs.forEach {
                fb.put(it)
            }
            fb.position(0)
            data(fb, Usage.STATIC_DRAW)
        }

        vboAttr = VertexAttribute(0, 3, VertexAttrType.FLOAT, false, 3 * 4, 0)

        glClearColor(0.3f, 0.3f, 0.3f, 1.0f)
    }

    override fun loop() {
        glClear(GL_COLOR_BUFFER_BIT)
        program?.use()
        vbo?.bind(BufferTarget.ARRAY)

        glEnableVertexAttribArray(vboAttr)
        glVertexAttribPointer(vboAttr)

        GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3)
    }

    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            val app = st.learnopengl.apps.basic.HelloTriangle(1280, 720, "Hello Triangle")
            app.run()
        }
    }
}